#include "VisualDocumentViewAdaptor.h"
#include "VisualDocumentPlugin.h"

#include <QtNodes/ConnectionStyle>
#include <QtNodes/DataFlowGraphModel>
#include <QtNodes/DataFlowGraphicsScene>
#include <QtNodes/GraphicsView>
#include <QtNodes/NodeData>
#include <QtNodes/NodeDelegateModelRegistry>
#include <QtNodes/internal/NodeGraphicsObject.hpp>

#include <QtPrintSupport/QtPrintSupport>


VisualDocumentViewAdaptor::VisualDocumentViewAdaptor(shell::Access_interface & shell_access, VisualDocumentPlugin * plugin,
                        std::shared_ptr<shell::DocumentAdaptor_interface> document_adaptor)
    : _shell_access(shell_access)
    , _plugin(plugin)
    , _document_adaptor(document_adaptor)
{
    if (!document_adaptor)
        _document_adaptor = _plugin->createDocumentAdaptor(shell_access);

    VisualDocumentAdaptor * doc = dynamic_cast<VisualDocumentAdaptor *>(_document_adaptor.get());

    Q_ASSERT(doc);

    _scene  = new QtNodes::DataFlowGraphicsScene(doc->model());
    _editor = new QtNodes::GraphicsView(_scene);

//    connect(_scene, &QGraphicsScene::changed, this, [this, doc](const QList<QRectF> &){
//        doc->setModified(true);
//    });

    connect(_scene, &QtNodes::BasicGraphicsScene::nodeClicked, this, [this](QtNodes::NodeId const nodeId){
        QtNodes::NodeGraphicsObject * node = _scene->nodeGraphicsObject(nodeId);
        if (node) {
            QtNodes::AbstractGraphModel & model = node->graphModel();
            QJsonObject json_object = model.saveNode(nodeId);
            QString title = QString(tr("Property of Node%1")).arg(nodeId);
            const auto it = json_object.find("internal-data");
            if (it.value().isObject()) {
                _shell_access.setPanelTitle("visual-calculator-properties", title);
                _shell_access.sendDataToPanel("visual-calculator-properties", "VC Properties", it.value().toObject());
            }
        }
    });
}

QWidget * VisualDocumentViewAdaptor::document_widget()
{
    return _editor;
}

shell::Document_plugin * VisualDocumentViewAdaptor::plugin()
{
    return _plugin;
}

QWidget * VisualDocumentViewAdaptor::copyWidget()
{
    return new QtNodes::GraphicsView(_scene);
}

QString VisualDocumentViewAdaptor::loadFile(const QString &file_name)
{
    Q_ASSERT(_document_adaptor);
    QString error_string = _document_adaptor->loadFile(file_name);
    return error_string;
}

void VisualDocumentViewAdaptor::setReadOnly()
{
//    _editor->setReadOnly(true);
}

void VisualDocumentViewAdaptor::print(QPrinter * printer)
{
    QPainter painter(printer);
    painter.setRenderHint(QPainter::Antialiasing);
    _scene->render(&painter);
}

void VisualDocumentViewAdaptor::cutFromDocument()
{

}

void VisualDocumentViewAdaptor::copyFromDocument()
{

}

void VisualDocumentViewAdaptor::pasteToDocument()
{

}

bool VisualDocumentViewAdaptor::hasSelection()
{
    return false;
}

bool VisualDocumentViewAdaptor::hasUndo()
{
    return _scene->undoStack().canUndo();
}

bool VisualDocumentViewAdaptor::hasRedo()
{
    return _scene->undoStack().canRedo();
}

void VisualDocumentViewAdaptor::zoomIn()
{

}

void VisualDocumentViewAdaptor::zoomOut()
{

}

void VisualDocumentViewAdaptor::zoomZero()
{

}

QPair<int,int> VisualDocumentViewAdaptor::getLineCol() const
{
//    QTextCursor cursor = _editor->textCursor();
    return {0,0};
}

void VisualDocumentViewAdaptor::setLineCol(QPair<int,int> )
{
//    QTextCursor cursor = _editor->textCursor();
//    cursor.movePosition(QTextCursor::Start);
//    cursor.movePosition(QTextCursor::Down, QTextCursor::MoveAnchor, line_col.first-1);
//    cursor.movePosition(QTextCursor::Right, QTextCursor::MoveAnchor, line_col.second-1);
    //    _editor->setTextCursor(cursor);
}

void VisualDocumentViewAdaptor::addNode(const QString &node_name)
{
    VisualDocumentAdaptor * doc = dynamic_cast<VisualDocumentAdaptor *>(_document_adaptor.get());
    Q_ASSERT(doc);
    doc->model().addNode(node_name);
}
